home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / sun4.md / devSCSI0.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  34KB  |  1,058 lines

  1. /* 
  2.  * devSCSI0.c --
  3.  *
  4.  *    Driver routines specific to the original Sun Host Adaptor.
  5.  *    This lives either on the Multibus or the VME.  It does
  6.  *    not support dis-connect/connect.
  7.  *     This information is derived from Sun's "Manual for Sun SCSI
  8.  *    Programmers", which details the layout of the this implementation
  9.  *    of the Host Adaptor, the device that interfaces to the SCSI Bus.
  10.  *
  11.  * Copyright 1986 Regents of the University of California
  12.  * Permission to use, copy, modify, and distribute this
  13.  * software and its documentation for any purpose and without
  14.  * fee is hereby granted, provided that the above copyright
  15.  * notice appear in all copies.  The University of California
  16.  * makes no representations about the suitability of this
  17.  * software for any purpose.  It is provided "as is" without
  18.  * express or implied warranty.
  19.  */
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/sun4.md/devSCSI0.c,v 9.3 91/08/19 13:47:59 jhh Exp $ SPRITE (Berkeley)";
  23. #endif not lint
  24.  
  25.  
  26. #include <sprite.h>
  27. #include <mach.h>
  28. #include <scsi0.h>
  29. #include <dev.h>
  30. #include <devInt.h>
  31. #include <sys/scsi.h>
  32. #include <scsiHBA.h>
  33. #include <scsiDevice.h>
  34. #include <devMultibus.h>
  35. #include <sync.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <bstring.h>
  39. #include <string.h>
  40.  
  41. /*
  42.  * The device registers for the original Sun SCSI Host Adaptor.
  43.  * Through these registers the SCSI bus is controlled.  There are the
  44.  * usual status and control bits, and there are also registers through
  45.  * which command blocks and status blocks are transmitted.  This format
  46.  * is defined on Page 10. of Sun's SCSI Programmers' Manual.
  47.  */
  48. typedef struct CtrlRegs {
  49.     unsigned char data;        /* Data register.  Contains the ID of the
  50.                  * SCSI "target", or controller, for the 
  51.                  * SELECT phase. Also, leftover odd bytes
  52.                  * are left here after a read. */
  53.     unsigned char pad1;        /* The other half of the data register which
  54.                  * is never used by us */
  55.     unsigned char commandStatus;/* Command and status blocks are passed
  56.                  * in and out through this */
  57.     unsigned char pad2;        /* The other half of the commandStatus register
  58.                  * which never contains useful information */
  59.     unsigned short control;    /* The SCSI interface control register.
  60.                  * Bits are defined below */
  61.     unsigned short pad3;
  62.     unsigned int dmaAddress;    /* Target address for DMA */
  63.     short     dmaCount;    /* Number of bytes for DMA.  Initialize this
  64.                  * this to minus the byte count minus 1 more,
  65.                  * and the device increments to -1. If this
  66.                  * is 0 or 1 after a transfer then there was
  67.                  * a DMA overrun. */
  68.     unsigned char pad4;
  69.     unsigned char intrVector;    /* For VME, Index into autovector */
  70. } CtrlRegs;
  71.  
  72. /*
  73.  * Control bits in the SCSI Host Interface control register.
  74.  *
  75.  *    SCSI_PARITY_ERROR There was a parity error on the SCSI bus.
  76.  *    SCSI_BUS_ERROR    There was a bus error on the SCSI bus.
  77.  *    SCSI_ODD_LENGTH An odd byte is left over in the data register after
  78.  *            a read or write.
  79.  *    SCSI_INTERRUPT_REQUEST bit checked by polling routine.  If a command
  80.  *            block is sent and the SCSI_INTERRUPT_ENABLE bit is
  81.  *            NOT set, then the appropriate thing to do is to
  82.  *            wait around (poll) until this bit is set.
  83.  *    SCSI_REQUEST    Set by controller to start byte passing handshake.
  84.  *    SCSI_MESSAGE    Set by a controller during message phase.
  85.  *    SCSI_COMMAND    Set during the command, status, and messages phase.
  86.  *    SCSI_INPUT    If set means data (or commandStatus) set by device.
  87.  *    SCSI_PARITY    Used to test the parity checking hardware.
  88.  *    SCSI_BUSY    Set by controller after it has been selected.
  89.  *  The following bits can be set by the CPU.
  90.  *    SCSI_SELECT    Set by the host when it want to select a controller.
  91.  *    SCSI_RESET    Set by the host when it want to reset the SCSI bus.
  92.  *    SCSI_PARITY_ENABLE    Enable parity checking on transfer
  93.  *    SCSI_WORD_MODE        Send 2 bytes at a time
  94.  *    SCSI_DMA_ENABLE        Do DMA, always used.
  95.  *    SCSI_INTERRUPT_ENABLE    Interrupt upon completion.
  96.  */
  97. #define SCSI_PARITY_ERROR        0x8000
  98. #define SCSI_BUS_ERROR            0x4000
  99. #define SCSI_ODD_LENGTH            0x2000
  100. #define SCSI_INTERRUPT_REQUEST        0x1000
  101. #define SCSI_REQUEST            0x0800
  102. #define SCSI_MESSAGE            0x0400
  103. #define SCSI_COMMAND            0x0200
  104. #define SCSI_INPUT            0x0100
  105. #define SCSI_PARITY            0x0080
  106. #define SCSI_BUSY            0x0040
  107. #define SCSI_SELECT            0x0020
  108. #define SCSI_RESET            0x0010
  109. #define SCSI_PARITY_ENABLE        0x0008
  110. #define SCSI_WORD_MODE            0x0004
  111. #define SCSI_DMA_ENABLE            0x0002
  112. #define SCSI_INTERRUPT_ENABLE        0x0001
  113.  
  114. /* Forward declaration. */
  115. typedef struct Controller Controller;
  116.  
  117. /*
  118.  * Device - The data structure containing information about a device. One of
  119.  * these structure is kept for each attached device. Note that is structure
  120.  * is casted into a ScsiDevice and returned to higher level software.
  121.  * This implies that the ScsiDevice must be the first field in this
  122.  * structure.
  123.  */
  124.  
  125. typedef struct Device {
  126.     ScsiDevice handle;    /* Scsi Device handle. This is the only part
  127.              * of this structure visible to higher 
  128.              * level software. MUST BE FIRST FIELD IN STRUCTURE.
  129.              */
  130.     int    targetID;    /* SCSI Target ID of this device. Note that
  131.              * the LUN is store in the device handle.
  132.              */
  133.     Controller *ctrlPtr;    /* Controller to which device is attached. */
  134.            /*
  135.             * The following part of this structure is 
  136.             * used to handle SCSI commands that return 
  137.             * CHECK status. To handle the REQUEST SENSE
  138.             * command we must: 1) Save the state of the current
  139.             * command into the "struct FrozenCommand". 2) Submit
  140.             * a request sense command formatted in SenseCmd
  141.             * to the device.
  142.             */
  143.     struct FrozenCommand {               
  144.     ScsiCmd    *scsiCmdPtr;      /* The frozen command. */
  145.     unsigned char statusByte; /* It's SCSI status byte, Will always have
  146.                    * the check bit set.  */
  147.     int amountTransferred;    /* Number of bytes transferred by this 
  148.                    * command.  */
  149.     } frozen;    
  150.     char senseBuffer[DEV_MAX_SENSE_BYTES]; /* Data buffer for request sense */
  151.     ScsiCmd        SenseCmd;         /* Request sense command buffer. */
  152. } Device;
  153.  
  154. /*
  155.  * Controller - The Data structure describing a sun SCSI0 controller. One
  156.  * of these structures exists for each active SCSI0 HBA on the system. Each
  157.  * controller may have from zero to 56 (7 targets each with 8 logical units)
  158.  * devices attached to it. 
  159.  */
  160. struct Controller {
  161.     volatile CtrlRegs *regsPtr;    /* Pointer to the registers
  162.                                     of this controller. */
  163.     int        dmaState;    /* DMA state for this controller, defined below. */
  164.     char    *name;    /* String for error message for this controller.  */
  165.     DevCtrlQueues devQueues;    /* Device queues for devices attached to this
  166.                  * controller.     */
  167.     Sync_Semaphore mutex; /* Lock protecting controller's data structures. */
  168.     Device     *devPtr;       /* Current active command. */
  169.     ScsiCmd   *scsiCmdPtr; /* Current active command. */
  170.     Address   dmaBuffer;  /* dma buffer allocated for request. */
  171.     Device  *devicePtr[8][8]; /* Pointers to the device
  172.                                * attached to the
  173.                    * controller index by [targetID][LUN].
  174.                    * NIL if device not attached yet. Zero if
  175.                    * device conflicts with HBA address.  */
  176.  
  177. };
  178.  
  179. /* 
  180.  * SCSI_WAIT_LENGTH - the number of microseconds that the host waits for
  181.  *    various control lines to be set on the SCSI bus.  The largest wait
  182.  *    time is when a controller is being selected.  This delay is
  183.  *    called the Bus Abort delay and is about 250 milliseconds.
  184.  */
  185. #define SCSI_WAIT_LENGTH        250000
  186.  
  187. /*
  188.  * Possible values for the dmaState state field of a controller.
  189.  *
  190.  * DMA_RECEIVE  - data is being received from the device, such as on
  191.  *    a read, inquiry, or request sense.
  192.  * DMA_SEND     - data is being send to the device, such as on a write.
  193.  * DMA_INACTIVE - no data needs to be transferred.
  194.  */
  195.  
  196. #define DMA_RECEIVE 0
  197. #define    DMA_SEND 1
  198. #define    DMA_INACTIVE 2
  199. /*
  200.  * Test, mark, and unmark the controller as busy.
  201.  */
  202. #define    IS_CTRL_BUSY(ctrlPtr)    ((ctrlPtr)->scsiCmdPtr != (ScsiCmd *) NIL)
  203. #define    SET_CTRL_BUSY(ctrlPtr,scsiCmdPtr) \
  204.         ((ctrlPtr)->scsiCmdPtr = (scsiCmdPtr))
  205. #define    SET_CTRL_FREE(ctrlPtr)    ((ctrlPtr)->scsiCmdPtr = (ScsiCmd *) NIL)
  206.  
  207. /*
  208.  * MAX_SCSI0_CTRLS - Maximum number of SCSI0 controllers attached to the
  209.  *             system. We set this to the maximum number of VME slots
  210.  *             in any Sun2 system currently available.
  211.  */
  212. #define    MAX_SCSI0_CTRLS    4
  213. static Controller *Controllers[MAX_SCSI0_CTRLS];
  214. /*
  215.  * Highest number controller we have probed for.
  216.  */
  217. static int numSCSI0Controllers = 0;
  218.  
  219. int devSCSI0Debug = 0;
  220.  
  221. static void RequestDone _ARGS_ ((Device *devPtr, ScsiCmd *scsiCmdPtr,
  222.     ReturnStatus status, unsigned int scsiStatusByte, int amountTransferred));
  223. static ReturnStatus Wait _ARGS_ ((Controller *ctrlPtr,
  224.     int condition, Boolean reset));
  225. static int              SpecialSenseProc _ARGS_((ScsiCmd *scsiCmdPtr,
  226.                         ReturnStatus status,
  227.                         int statusByte,
  228.                         int byteCount,
  229.                         int senseLength,
  230.                         Address senseDataPtr));
  231.  
  232.  
  233. /*
  234.  *----------------------------------------------------------------------
  235.  *
  236.  * Probe --
  237.  *
  238.  *    Probe memory for the old-style VME SCSI interface.  We rely
  239.  *    on the fact that this occupies 4K of address space. 
  240.  *
  241.  * Results:
  242.  *    TRUE if the host adaptor was found.
  243.  *
  244.  * Side effects:
  245.  *    None.
  246.  *
  247.  *----------------------------------------------------------------------
  248.  */
  249. static Boolean
  250. Probe(address)
  251.     int address;            /* Alledged controller address */
  252. {
  253.     ReturnStatus    status;
  254.     register volatile CtrlRegs *regsPtr = (CtrlRegs *)address;
  255.     short value;
  256.  
  257.     /*
  258.      * Touch the device. If it exists it occupies 4K.
  259.      */
  260.     value = 0x4BCC;
  261.     status = Mach_Probe(sizeof(regsPtr->dmaCount), (char *) &value,
  262.             (char *) &(regsPtr->dmaCount));
  263.     if (status == SUCCESS) {
  264.     value = 0x5BCC;
  265.     status = Mach_Probe(sizeof(regsPtr->dmaCount),(char *) &value,
  266.               ((char *) &(regsPtr->dmaCount)) + 0x800);
  267.     }
  268.     return(status == SUCCESS);
  269. }
  270.  
  271.  
  272. /*
  273.  *----------------------------------------------------------------------
  274.  *
  275.  * Reset --
  276.  *
  277.  *    Reset a SCSI bus controlled by the orignial Sun Host Adaptor.
  278.  *
  279.  * Results:
  280.  *    None.
  281.  *
  282.  * Side effects:
  283.  *    Reset the controller.
  284.  *
  285.  *----------------------------------------------------------------------
  286.  */
  287. static void
  288. Reset(ctrlPtr)
  289.     Controller *ctrlPtr;
  290. {
  291.     volatile CtrlRegs *regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  292.  
  293.     regsPtr->control = SCSI_RESET;
  294.     MACH_DELAY(100);
  295.     regsPtr->control = 0;
  296. }
  297.  
  298. /*
  299.  *----------------------------------------------------------------------
  300.  *
  301.  * SendCommand --
  302.  *
  303.  *      Send a command to a controller on the old-style SCSI Host Adaptor
  304.  *      indicated by devPtr.  
  305.  *
  306.  *    Note: the ID of the controller is never placed on the bus
  307.  *    (contrary to standard protocol, but necessary for the early Sun
  308.  *    SCSI interface).
  309.  *
  310.  * Results:
  311.  *    An error code.
  312.  *
  313.  * Side effects:
  314.  *    Those of the command (Read, write etc.)
  315.  *
  316.  *----------------------------------------------------------------------
  317.  */
  318. static ReturnStatus
  319. SendCommand(devPtr, scsiCmdPtr)
  320.     Device    *devPtr;        /* Device to sent to. */
  321.     ScsiCmd    *scsiCmdPtr;        /* Command to send. */
  322. {
  323.     register ReturnStatus status;
  324.     register volatile CtrlRegs *regsPtr;/* Host Adaptor registers */
  325.     char *charPtr;            /* Used to put the control block
  326.                      * into the commandStatus register */
  327.     int bits = 0;            /* variable bits to OR into control */
  328.     int targetID;            /* Id of the SCSI device to select */
  329.     int size;                /* Number of bytes to transfer */
  330.     Address addr;            /* Kernel address of transfer */
  331.     Controller    *ctrlPtr;        /* HBA of device. */
  332.     int    i;
  333.  
  334.     /*
  335.      * Set current active device and command for this controller.
  336.      */
  337.     ctrlPtr = devPtr->ctrlPtr;
  338.     SET_CTRL_BUSY(ctrlPtr,scsiCmdPtr);
  339.     ctrlPtr->dmaBuffer = (Address) NIL;
  340.     ctrlPtr->devPtr = devPtr;
  341.     size = scsiCmdPtr->bufferLen;
  342.     addr = scsiCmdPtr->buffer;
  343.     targetID = devPtr->targetID;
  344.     regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  345.     if (size == 0) {
  346.     ctrlPtr->dmaState = DMA_INACTIVE;
  347.     } else {
  348.     ctrlPtr->dmaState = (scsiCmdPtr->dataToDevice) ? DMA_SEND :
  349.                              DMA_RECEIVE;
  350.     }
  351.    /*
  352.      * Check against a continuously busy bus.  This stupid condition would
  353.      * fool the code below that tries to select a device.
  354.      */
  355.     for (i=0 ; i < SCSI_WAIT_LENGTH ; i++) {
  356.     if ((regsPtr->control & SCSI_BUSY) == 0) {
  357.         break;
  358.     } else {
  359.         MACH_DELAY(10);
  360.     }
  361.     }
  362.     if (i == SCSI_WAIT_LENGTH) {
  363.     Reset(ctrlPtr);
  364.     printf("Warning: %s SCSI bus stuck busy\n", ctrlPtr->name);
  365.     return(FAILURE);
  366.     }
  367.     /*
  368.      * Select the device.  Sun's SCSI Programmer's Manual recommends
  369.      * resetting the SCSI_WORD_MODE bit so that the byte packing hardware
  370.      * is reset and the data byte that has the target ID gets transfered
  371.      * correctly.  After this, the target's ID is put in the data register,
  372.      * the SELECT bit is set, and we wait until the device responds
  373.      * by setting the BUSY bit.  The ID bit of the host adaptor is not
  374.      * put in the data word because of problems with Sun's Host Adaptor.
  375.      */
  376.     regsPtr->control = 0;
  377.     regsPtr->data = (1 << targetID);
  378.     regsPtr->control = SCSI_SELECT;
  379.     status = Wait(ctrlPtr, SCSI_BUSY, FALSE);
  380.     if (status != SUCCESS) {
  381.     regsPtr->data = 0;
  382.     regsPtr->control = 0;
  383.         printf("Warning: %s: can't select device at %s\n", 
  384.                  ctrlPtr->name, devPtr->handle.locationName);
  385.     return(status);
  386.     }
  387.     /*
  388.      * Set up the interface's registers for the transfer.  The DMA address
  389.      * is relative to the multibus memory so the kernel's base address
  390.      * for multibus memory is subtracted from 'addr'. The host adaptor
  391.      * increments the dmaCount register until it reaches -1, hence the
  392.      * funny initialization. See page 4 of Sun's SCSI Prog. Manual.
  393.      */
  394.     if (ctrlPtr->dmaState != DMA_INACTIVE) {
  395.     ctrlPtr->dmaBuffer = addr = VmMach_DMAAlloc(size,scsiCmdPtr->buffer);
  396.     }
  397.     if (addr == (Address) NIL) {
  398.     panic("%s can't allocate DMA buffer of %d bytes\n", 
  399.             devPtr->handle.locationName, size);
  400.     }
  401.     regsPtr->dmaAddress = (int)(addr - VMMACH_DMA_START_ADDR);
  402.     regsPtr->dmaCount = -size - 1;
  403.     bits = SCSI_WORD_MODE | SCSI_DMA_ENABLE | SCSI_INTERRUPT_ENABLE;
  404.     regsPtr->control = bits;
  405.  
  406.     /*
  407.      * Stuff the control block through the commandStatus register.
  408.      * The handshake on the SCSI bus is visible here:  we have to
  409.      * wait for the Request line on the SCSI bus to be raised before
  410.      * we can send the next command byte to the controller.  All commands
  411.      * are of "group 0" which means they are 6 bytes long.
  412.      */
  413.     charPtr = scsiCmdPtr->commandBlock;
  414.     for (i=0 ; i < scsiCmdPtr->commandBlockLen ; i++) {
  415.     status = Wait(ctrlPtr, SCSI_REQUEST, TRUE);
  416.     if (status != SUCCESS) {
  417.         printf("Warning: %s couldn't send command block byte %d\n",
  418.                  ctrlPtr->name, i);
  419.         return(status);
  420.     }
  421.     /*
  422.      * The device keeps the Control/Data line set while it
  423.      * is accepting control block bytes.
  424.      */
  425.     if ((regsPtr->control & SCSI_COMMAND) == 0) {
  426.         Reset(ctrlPtr);
  427.         printf("Warning: %s: device %s dropped command line\n",
  428.                 ctrlPtr->name, devPtr->handle.locationName);
  429.         return(DEV_HANDSHAKE_ERROR);
  430.     }
  431.         regsPtr->commandStatus = *charPtr;
  432.     charPtr++;
  433.     }
  434.     return(SUCCESS);
  435. }
  436.  
  437. /*
  438.  *----------------------------------------------------------------------
  439.  *
  440.  * GetStatusByte --
  441.  *
  442.  *    Complete an SCSI command by getting the status bytes from
  443.  *    the device and waiting for the ``command complete''
  444.  *    message that follows the status bytes.  If the command has
  445.  *    additional ``sense data'' then this routine issues the
  446.  *    SCSI_REQUEST_SENSE command to get the sense data.
  447.  *
  448.  * Results:
  449.  *    An error code if the status didn't come through or it
  450.  *    indicated an error.
  451.  *
  452.  * Side effects:
  453.  *    None.
  454.  *
  455.  *----------------------------------------------------------------------
  456.  */
  457. static ReturnStatus
  458. GetStatusByte(ctrlPtr, statusBytePtr)
  459.     Controller *ctrlPtr;
  460.     unsigned char *statusBytePtr;
  461. {
  462.     register ReturnStatus status;
  463.     register volatile CtrlRegs *regsPtr;
  464.     short message;
  465.     char statusByte;
  466.     int numStatusBytes = 0;
  467.  
  468.     regsPtr = ctrlPtr->regsPtr;
  469.     *statusBytePtr = 0;
  470.     for (;;) {
  471.     /*
  472.      * Could probably wait either on the INTERUPT_REQUEST bit or the
  473.      * REQUEST bit.  Reading the byte out of the commandStatus
  474.      * register acknowledges the REQUEST and clears these bits.  Here
  475.      * we grab bytes until the MESSAGE bit indicates that all the
  476.      * status bytes have been received and that the byte in the
  477.      * commandStatus register is the message byte.
  478.      */
  479.     status = Wait(ctrlPtr, SCSI_REQUEST, TRUE);
  480.     if (status != SUCCESS) {
  481.         printf("Warning: %s: wait error after %d status bytes\n",
  482.                  ctrlPtr->name, numStatusBytes);
  483.         break;
  484.     }
  485.     if (regsPtr->control & SCSI_MESSAGE) {
  486.         message = regsPtr->commandStatus & 0xff;
  487.         if (message != SCSI_COMMAND_COMPLETE) {
  488.         printf("Warning %s: Unexpected message 0x%x\n",
  489.                      ctrlPtr->name, message);
  490.         }
  491.         break;
  492.     } else {
  493.         /*
  494.          * This is another status byte.  Place the first status
  495.          * bytes into the status block.
  496.          */
  497.         statusByte = regsPtr->commandStatus;
  498.         if (numStatusBytes < 1) {
  499.         *statusBytePtr = statusByte;
  500.         }
  501.         numStatusBytes++;
  502.     }
  503.     }
  504.     return(status);
  505. }
  506.  
  507. /*
  508.  *----------------------------------------------------------------------
  509.  *
  510.  * Wait --
  511.  *
  512.  *    Wait for a condition in the SCSI controller.
  513.  *
  514.  * Results:
  515.  *    SUCCESS if the condition occurred before a threashold time limit,
  516.  *    DEV_TIMEOUT otherwise.
  517.  *
  518.  * Side effects:
  519.  *    This resets the SCSI bus if the reset parameter is true and
  520.  *    the condition bits are not set by the controller before timeout..
  521.  *
  522.  *----------------------------------------------------------------------
  523.  */
  524. static ReturnStatus
  525. Wait(ctrlPtr, condition, reset)
  526.     Controller *ctrlPtr;
  527.     int condition;
  528.     Boolean reset;
  529. {
  530.     volatile CtrlRegs *regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  531.     register int i;
  532.     ReturnStatus status = DEV_TIMEOUT;
  533.     register int control = 0;
  534.  
  535.     for (i=0 ; i < SCSI_WAIT_LENGTH ; i++) {
  536.     control = regsPtr->control;
  537.     if (devSCSI0Debug && i < 5) {
  538.         printf("%d/%x ", i, control);
  539.     }
  540.     if (control & condition) {
  541.         return(SUCCESS);
  542.     }
  543.     if (control & SCSI_BUS_ERROR) {
  544.         printf("Warning: %s : SCSI bus error\n",ctrlPtr->name);
  545.         status = DEV_DMA_FAULT;
  546.         break;
  547.     } else if (control & SCSI_PARITY_ERROR) {
  548.         printf("Warning: %s: parity error\n",ctrlPtr->name);
  549.         status = DEV_DMA_FAULT;
  550.         break;
  551.     }
  552.     MACH_DELAY(10);
  553.     }
  554.     if (devSCSI0Debug) {
  555.     printf("DevSCSI0Wait: timed out, control = %x.\n", control);
  556.     }
  557.     if (reset) {
  558.     Reset(ctrlPtr);
  559.     }
  560.     return(status);
  561. }
  562.  
  563. /*
  564.  *----------------------------------------------------------------------
  565.  *
  566.  * entryAvailProc --
  567.  *
  568.  *    Act upon an entry becomming available in the queue for this
  569.  *    controller. This routine is the Dev_Queue callback function that
  570.  *    is called whenever work becomes available for this controller. 
  571.  *    If the controller is not already busy we dequeue and start the
  572.  *    request.
  573.  *    NOTE: This routine is also called from DevSCSI0Intr to start the
  574.  *    next request after the previously one finishes.
  575.  *
  576.  * Results:
  577.  *    None.
  578.  *
  579.  * Side effects:
  580.  *    Request may be dequeue and submitted to the device. Request callback
  581.  *    function may be called.
  582.  *
  583.  *----------------------------------------------------------------------
  584.  */
  585.  
  586. static Boolean
  587. entryAvailProc(clientData, newRequestPtr) 
  588.    ClientData    clientData;    /* Really the Device this request ready. */
  589.    List_Links *newRequestPtr;    /* The new SCSI request. */
  590. {
  591.     register Device *devPtr; 
  592.     register Controller *ctrlPtr;
  593.     register ScsiCmd    *scsiCmdPtr;
  594.     ReturnStatus    status;
  595.  
  596.     devPtr = (Device *) clientData;
  597.     ctrlPtr = devPtr->ctrlPtr;
  598.     /*
  599.      * If we are busy (have an active request) just return. Otherwise 
  600.      * start the request.
  601.      */
  602.  
  603.     if (IS_CTRL_BUSY(ctrlPtr)) { 
  604.     return FALSE;
  605.     }
  606. again:
  607.     scsiCmdPtr = (ScsiCmd *) newRequestPtr;
  608.     devPtr = (Device *) clientData;
  609.     status = SendCommand( devPtr, scsiCmdPtr);
  610.     /*    
  611.      * If the command couldn't be started do the callback function.
  612.      */
  613.     if (status != SUCCESS) {
  614.      RequestDone(devPtr,scsiCmdPtr,status,0,0);
  615.     }
  616.     if (!IS_CTRL_BUSY(ctrlPtr)) { 
  617.         newRequestPtr = Dev_QueueGetNextFromSet(ctrlPtr->devQueues,
  618.                 DEV_QUEUE_ANY_QUEUE_MASK,&clientData);
  619.     if (newRequestPtr != (List_Links *) NIL) { 
  620.         goto again;
  621.     }
  622.     }
  623.     return TRUE;
  624.  
  625. }   
  626.  
  627.  
  628. /*
  629.  *----------------------------------------------------------------------
  630.  *
  631.  *  SpecialSenseProc --
  632.  *
  633.  *    Special function used for HBA generated REQUEST SENSE. A SCSI
  634.  *    command request with this function as a call back proc will
  635.  *    be processed by routine RequestDone as a result of a 
  636.  *    REQUEST SENSE. This routine is never called.
  637.  *
  638.  * Results:
  639.  *    None.
  640.  *
  641.  * Side effects:
  642.  *    None.
  643.  *
  644.  *----------------------------------------------------------------------
  645.  */
  646. /*ARGSUSED*/
  647. static int
  648. SpecialSenseProc(scsiCmdPtr, status, statusByte, byteCount, senseLength,
  649.          senseDataPtr)
  650.     ScsiCmd        *scsiCmdPtr;
  651.     ReturnStatus    status;
  652.     unsigned char    statusByte;
  653.     int            byteCount;
  654.     int            senseLength;
  655.     Address        senseDataPtr;
  656. {
  657.     return 0;
  658. }
  659.  
  660.  
  661. /*
  662.  *----------------------------------------------------------------------
  663.  *
  664.  * RequestDone --
  665.  *
  666.  *    Process a request that has finished. Unless a SCSI check condition
  667.  *    bit is present in the status returned, the request call back
  668.  *    function is called.  If check condition is set we fire off a
  669.  *    SCSI REQUEST SENSE to get the error sense bytes from the device.
  670.  *
  671.  * Results:
  672.  *    None.
  673.  *
  674.  * Side effects:
  675.  *    The call back function may be called.
  676.  *
  677.  *----------------------------------------------------------------------
  678.  */
  679.  
  680. static void
  681. RequestDone(devPtr,scsiCmdPtr,status,scsiStatusByte,amountTransferred)
  682.     Device    *devPtr;    /* Device for request. */
  683.     ScsiCmd    *scsiCmdPtr;    /* Request that finished. */
  684.     ReturnStatus status;    /* Status returned. */
  685.     unsigned int scsiStatusByte;    /* SCSI Status Byte. */
  686.     int        amountTransferred; /* Amount transferred by command. */
  687. {
  688.     ReturnStatus    senseStatus;
  689.     Controller            *ctrlPtr = devPtr->ctrlPtr;
  690.  
  691.  
  692.     if (devSCSI0Debug > 3) {
  693.     printf("RequestDone for %s status 0x%x scsistatus 0x%x count %d\n",
  694.         devPtr->handle.locationName, status,scsiStatusByte,
  695.         amountTransferred);
  696.     }
  697.     if (ctrlPtr->dmaState != DMA_INACTIVE) {
  698.     VmMach_DMAFree(scsiCmdPtr->bufferLen,ctrlPtr->dmaBuffer);
  699.     ctrlPtr->dmaState = DMA_INACTIVE;
  700.     }
  701.     /*
  702.      * First check to see if this is the reponse of a HBA generated 
  703.      * REQUEST SENSE command.  If this is the case, we can process
  704.      * the callback of the frozen command for this device and
  705.      * allow the flow of command to the device to be resummed.
  706.      */
  707.     if (scsiCmdPtr->doneProc == SpecialSenseProc) {
  708.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  709.     (devPtr->frozen.scsiCmdPtr->doneProc)(devPtr->frozen.scsiCmdPtr, 
  710.             SUCCESS,
  711.             devPtr->frozen.statusByte, 
  712.             devPtr->frozen.amountTransferred,
  713.             amountTransferred,
  714.             devPtr->senseBuffer);
  715.      MASTER_LOCK(&(ctrlPtr->mutex));
  716.      SET_CTRL_FREE(ctrlPtr);
  717.      return;
  718.     }
  719.     /*
  720.      * This must be a outside request finishing. If the request 
  721.      * suffered an error or the HBA or the scsi status byte
  722.      * says there is no error sense present, we can do the
  723.      * callback and free the controller.
  724.      */
  725.     if ((status != SUCCESS) || !SCSI_CHECK_STATUS(scsiStatusByte)) {
  726.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  727.     (scsiCmdPtr->doneProc)(scsiCmdPtr, status, scsiStatusByte,
  728.                    amountTransferred, 0, (char *) 0);
  729.      MASTER_LOCK(&(ctrlPtr->mutex));
  730.      SET_CTRL_FREE(ctrlPtr);
  731.      return;
  732.    } 
  733.    /*
  734.     * If we got here than the SCSI command came back from the device
  735.     * with the CHECK bit set in the status byte.
  736.     * Need to perform a REQUEST SENSE. Move the current request 
  737.     * into the frozen state and issue a REQUEST SENSE. 
  738.     */
  739.    devPtr->frozen.scsiCmdPtr = scsiCmdPtr;
  740.    devPtr->frozen.statusByte = scsiStatusByte;
  741.    devPtr->frozen.amountTransferred = amountTransferred;
  742.    DevScsiSenseCmd((ScsiDevice *)devPtr, DEV_MAX_SENSE_BYTES, 
  743.            devPtr->senseBuffer, &(devPtr->SenseCmd));
  744.    devPtr->SenseCmd.doneProc = SpecialSenseProc,
  745.    senseStatus = SendCommand(devPtr, &(devPtr->SenseCmd));
  746.    /*
  747.     * If we got an HBA error on the REQUEST SENSE we end the outside 
  748.     * command with the SUCCESS status but zero sense bytes returned.
  749.     */
  750.    if (senseStatus != SUCCESS) {
  751.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  752.     (scsiCmdPtr->doneProc)(scsiCmdPtr, status, scsiStatusByte,
  753.                    amountTransferred, 0, (char *) 0);
  754.     MASTER_LOCK(&(ctrlPtr->mutex));
  755.     SET_CTRL_FREE(ctrlPtr);
  756.    }
  757.  
  758. }
  759.  
  760. /*
  761.  *----------------------------------------------------------------------
  762.  *
  763.  * DevSCSI0Intr --
  764.  *
  765.  *    Handle interrupts from the SCSI controller.  This has to poll
  766.  *    through the possible SCSI controllers to find the one generating
  767.  *    the interrupt.  The usual action is to wake up whoever is waiting
  768.  *    for I/O to complete.  This may also start up another transaction
  769.  *    with the controller if there are things in its queue.
  770.  *
  771.  * Results:
  772.  *    TRUE if the SCSI controller was responsible for the interrupt
  773.  *    and this routine handled it.
  774.  *
  775.  * Side effects:
  776.  *    Usually a process is notified that an I/O has completed.
  777.  *
  778.  *----------------------------------------------------------------------
  779.  */
  780. /* ARGSUSED */ 
  781. Boolean
  782. DevSCSI0Intr(clientDataArg)
  783.     ClientData    clientDataArg;
  784. {
  785.     register Controller *ctrlPtr;
  786.     List_Links *newRequestPtr;
  787.     Device    *devPtr;
  788.     volatile CtrlRegs *regsPtr;
  789.     int        residual;
  790.     ReturnStatus    status;
  791.     unsigned char statusByte;
  792.     ClientData    clientData;
  793.  
  794.     ctrlPtr = (Controller *) clientDataArg;
  795.     regsPtr = ctrlPtr->regsPtr;
  796.     devPtr = ctrlPtr->devPtr;
  797.     MASTER_LOCK(&(ctrlPtr->mutex));
  798.     if (regsPtr->control & SCSI_INTERRUPT_REQUEST) {
  799.     if (regsPtr->control & SCSI_BUS_ERROR) {
  800.         if (regsPtr->dmaCount >= 0) {
  801.         /*
  802.          * A DMA overrun.  Unlikely with a disk but could
  803.          * happen while reading a large tape block.  Consider
  804.          * the I/O complete with no residual bytes
  805.          * un-transferred.
  806.          */
  807.         residual = 0;
  808.         } else {
  809.         /*
  810.          * A real Bus Error.  Complete the I/O but flag an error.
  811.          * The residual is computed because the Bus Error could
  812.          * have occurred after a number of sectors.
  813.          */
  814.         residual = -regsPtr->dmaCount -1;
  815.         }
  816.         /*
  817.          * The board needs to be reset to clear the Bus Error
  818.          * condition so no status bytes are grabbed.
  819.          */
  820.         Reset(ctrlPtr);
  821.         status = DEV_DMA_FAULT;
  822.         RequestDone(devPtr, ctrlPtr->scsiCmdPtr, status, 0,
  823.             ctrlPtr->scsiCmdPtr->bufferLen - residual);
  824.         if (!IS_CTRL_BUSY(ctrlPtr)) {
  825.         newRequestPtr = Dev_QueueGetNextFromSet(ctrlPtr->devQueues,
  826.                 DEV_QUEUE_ANY_QUEUE_MASK,&clientData);
  827.         if (newRequestPtr != (List_Links *) NIL) { 
  828.             (void) entryAvailProc(clientData,newRequestPtr);
  829.         }
  830.         }
  831.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  832.         return(TRUE);
  833.     } else {
  834.         /*
  835.          * Normal command completion.  Compute the residual,
  836.          * the number of bytes not transferred, check for
  837.          * odd transfer sizes, and finally get the completion
  838.          * status from the device.
  839.          */
  840.         if (!IS_CTRL_BUSY(ctrlPtr)) {
  841.         printf("Warning: Spurious interrupt from SCSI0\n");
  842.         Reset(ctrlPtr);
  843.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  844.         return(TRUE);
  845.         }
  846.         residual = -regsPtr->dmaCount -1;
  847.         if (regsPtr->control & SCSI_ODD_LENGTH) {
  848.         /*
  849.          * On a read the last odd byte is left in the data
  850.          * register.  On both reads and writes the number
  851.          * of bytes transferred as determined from dmaCount
  852.          * is off by one.  See Page 8 of Sun's SCSI
  853.          * Programmers' Manual.
  854.          */
  855.         if (!ctrlPtr->scsiCmdPtr->dataToDevice) {
  856.           *(volatile char *)(DEV_MULTIBUS_BASE + regsPtr->dmaAddress) =
  857.             regsPtr->data;
  858.             residual--;
  859.         } else {
  860.             residual++;
  861.         }
  862.         }
  863.         status = GetStatusByte(ctrlPtr,&statusByte);
  864.         RequestDone(devPtr, ctrlPtr->scsiCmdPtr, status, 
  865.             statusByte,
  866.             ctrlPtr->scsiCmdPtr->bufferLen - residual);
  867.         if (!IS_CTRL_BUSY(ctrlPtr)) {
  868.         newRequestPtr = Dev_QueueGetNextFromSet(ctrlPtr->devQueues,
  869.                 DEV_QUEUE_ANY_QUEUE_MASK,&clientData);
  870.         if (newRequestPtr != (List_Links *) NIL) { 
  871.             (void) entryAvailProc(clientData,newRequestPtr);
  872.         }
  873.         }
  874.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  875.         return(TRUE);
  876.     }
  877.     }
  878.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  879.     return (FALSE);
  880. }
  881.  
  882. /*
  883.  *----------------------------------------------------------------------
  884.  *
  885.  * ReleaseProc --
  886.  *
  887.  *    Device release proc for controller.
  888.  *
  889.  * Results:
  890.  *    None.
  891.  *
  892.  * Side effects:
  893.  *    None.
  894.  *
  895.  *----------------------------------------------------------------------
  896.  */
  897. /*ARGSUSED*/
  898. static ReturnStatus
  899. ReleaseProc(scsiDevicePtr)
  900.     ScsiDevice    *scsiDevicePtr;
  901. {
  902.     return SUCCESS;
  903. }
  904.  
  905.  
  906. /*
  907.  *----------------------------------------------------------------------
  908.  *
  909.  * DevSCSI0Init --
  910.  *
  911.  *    Check for the existant of the Sun SCSI0 HBA controller. If it
  912.  *    exists allocate data stuctures for it.
  913.  *
  914.  * Results:
  915.  *    TRUE if the controller exists, FALSE otherwise.
  916.  *
  917.  * Side effects:
  918.  *    Memory may be allocated.
  919.  *
  920.  *----------------------------------------------------------------------
  921.  */
  922. ClientData
  923. DevSCSI0Init(ctrlLocPtr)
  924.     DevConfigController    *ctrlLocPtr;    /* Controller location. */
  925. {
  926.     int    ctrlNum;
  927.     Boolean    found;
  928.     Controller *ctrlPtr;
  929.     int    i,j;
  930.  
  931.     /*
  932.      * See if the controller is there. 
  933.      */
  934.     ctrlNum = ctrlLocPtr->controllerID;
  935.     found =  Probe(ctrlLocPtr->address);
  936.     if (!found) {
  937.     return DEV_NO_CONTROLLER;
  938.     }
  939.     /*
  940.      * It's there. Allocate and fill in the Controller structure.
  941.      */
  942.     if (ctrlNum+1 > numSCSI0Controllers) {
  943.     numSCSI0Controllers = ctrlNum+1;
  944.     }
  945.     Controllers[ctrlNum] = ctrlPtr = (Controller *) malloc(sizeof(Controller));
  946.     bzero((char *) ctrlPtr, sizeof(Controller));
  947.     ctrlPtr->regsPtr = (volatile CtrlRegs *) (ctrlLocPtr->address);
  948.     ctrlPtr->regsPtr->intrVector = ctrlLocPtr->vectorNumber;
  949.     ctrlPtr->name = ctrlLocPtr->name;
  950.     Sync_SemInitDynamic(&(ctrlPtr->mutex),ctrlPtr->name);
  951.     /* 
  952.      * Initialized the name, device queue header, and the master lock.
  953.      * The controller comes up with no devices active and no devices
  954.      * attached.  Reserved the devices associated with the 
  955.      * targetID of the controller (7).
  956.      */
  957.     ctrlPtr->devQueues = Dev_CtrlQueuesCreate(&(ctrlPtr->mutex),entryAvailProc);
  958.     for (i = 0; i < 8; i++) {
  959.     for (j = 0; j < 8; j++) {
  960.         ctrlPtr->devicePtr[i][j] = (i == 7) ? (Device *) 0 : (Device *) NIL;
  961.     }
  962.     }
  963.     ctrlPtr->scsiCmdPtr = (ScsiCmd *) NIL;
  964.     Controllers[ctrlNum] = ctrlPtr;
  965.     Reset(ctrlPtr);
  966.     return (ClientData) ctrlPtr;
  967. }
  968.  
  969.  
  970. /*
  971.  *----------------------------------------------------------------------
  972.  *
  973.  * DevSCSI0ttachDevice --
  974.  *
  975.  *    Attach a SCSI device using the Sun SCSI0 HBA. 
  976.  *
  977.  * Results:
  978.  *    None.
  979.  *
  980.  * Side effects:
  981.  *    None.
  982.  *
  983.  *----------------------------------------------------------------------
  984.  */
  985.  
  986. ScsiDevice   *
  987. DevSCSI0AttachDevice(devicePtr, insertProc)
  988.     Fs_Device    *devicePtr;     /* Device to attach. */
  989.     void    (*insertProc) _ARGS_ ((List_Links *elementPtr,
  990.                                        List_Links *elementListHdrPtr));
  991.                                  /* Queue insert procedure. */
  992. {
  993.     Device *devPtr;
  994.     Controller    *ctrlPtr;
  995.     char   tmpBuffer[512];
  996.     int       length;
  997.     int       ctrlNum;
  998.     int       targetID, lun;
  999.  
  1000.     /*
  1001.      * First find the SCSI0 controller this device is on.
  1002.      */
  1003.     ctrlNum = SCSI_HBA_NUMBER(devicePtr);
  1004.     if ((ctrlNum > MAX_SCSI0_CTRLS) ||
  1005.     (Controllers[ctrlNum] == (Controller *) 0)) { 
  1006.     return (ScsiDevice  *) NIL;
  1007.     } 
  1008.     ctrlPtr = Controllers[ctrlNum];
  1009.     targetID = SCSI_TARGET_ID(devicePtr);
  1010.     lun = SCSI_LUN(devicePtr);
  1011.     /*
  1012.      * Allocate a device structure for the device and fill in the
  1013.      * handle part. This must be created before we grap the MASTER_LOCK.
  1014.      */
  1015.     devPtr = (Device *) malloc(sizeof(Device)); 
  1016.     bzero((char *) devPtr, sizeof(Device));
  1017.     devPtr->handle.devQueue = Dev_QueueCreate(ctrlPtr->devQueues,
  1018.                 1, insertProc, (ClientData) devPtr);
  1019.     devPtr->handle.locationName = "Unknown";
  1020.     devPtr->handle.LUN = lun;
  1021.     devPtr->handle.releaseProc = ReleaseProc;
  1022.     devPtr->handle.maxTransferSize = 63*1024;
  1023.     /*
  1024.      * See if the device is already present.
  1025.      */
  1026.     MASTER_LOCK(&(ctrlPtr->mutex));
  1027.     /*
  1028.      * A device pointer of zero means that targetID/LUN 
  1029.      * conflicts with that of the HBA. A NIL means the
  1030.      * device hasn't been attached yet.
  1031.      */
  1032.     if (ctrlPtr->devicePtr[targetID][lun] == (Device *) 0) {
  1033.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  1034.     (void) Dev_QueueDestroy(devPtr->handle.devQueue);
  1035.     free((char *) devPtr);
  1036.     return (ScsiDevice *) NIL;
  1037.     }
  1038.     if (ctrlPtr->devicePtr[targetID][lun] != (Device *) NIL) {
  1039.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  1040.     (void) Dev_QueueDestroy(devPtr->handle.devQueue);
  1041.     free((char *) devPtr);
  1042.     return (ScsiDevice *) (ctrlPtr->devicePtr[targetID][lun]);
  1043.     }
  1044.  
  1045.     ctrlPtr->devicePtr[targetID][lun] = devPtr;
  1046.     devPtr->targetID = targetID;
  1047.     devPtr->ctrlPtr = ctrlPtr;
  1048.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  1049.  
  1050.     (void) sprintf(tmpBuffer, "%s#%d Target %d LUN %d", ctrlPtr->name, ctrlNum,
  1051.             devPtr->targetID, devPtr->handle.LUN);
  1052.     length = strlen(tmpBuffer);
  1053.     devPtr->handle.locationName = (char *) strcpy(malloc(length+1),tmpBuffer);
  1054.  
  1055.     return (ScsiDevice *) devPtr;
  1056. }
  1057.  
  1058.